﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Security;
using System.Web.Profile;
using System.Text.RegularExpressions;

using log4net;
using imarks.Entity.Membership;
using imarks.BLL.Membership;
using imarks.Utility.Log;
using imarks.Utility;

namespace imarks.BLL.Membership
{
    public class MembershipService
    {
        private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private readonly MembershipProvider _provider;

        private RoleService roleService = new RoleService();

        public MembershipProvider Provider
        {
            get
            {
                return _provider;
            }
        }

        public MembershipService()
            : this(null)
        {
        }

        public MembershipService(MembershipProvider provider)
        {
            _provider = provider ?? System.Web.Security.Membership.Provider;
        }

        /// <summary>
        /// 验证用户
        /// </summary>
        /// <param name="userNameOrEmail">用户名或邮箱</param>
        /// <param name="password">密码</param>
        /// <returns>是否验证成功</returns>
        public bool ValidateUser(string userNameOrEmail, string password)
        {
            string userName = GetUserNameFromInput(userNameOrEmail);
            return _provider.ValidateUser(userName, password);
        }

        /// <summary>
        /// 验证用户
        /// </summary>
        /// <param name="userNameOrEmail">用户名或邮箱</param>
        /// <param name="password">密码</param>
        /// <param name="userName">用户名</param>
        /// <returns>是否验证成功</returns>
        public bool ValidateUser(string userNameOrEmail, string password, out string userName)
        {
            userName = GetUserNameFromInput(userNameOrEmail);
            bool result = false;
            try
            {
                result = _provider.ValidateUser(userName, password);
                log.Info(new LogMessage(userName, userName, LogObjectType.User, LogCode.USER_LOGIN));
                return result;
            }
            catch (Exception e)
            {
                log.Info(new LogMessage(userName, userName, LogObjectType.User, LogCode.USER_LOGIN, null, e));
                return result;
            }
        }

        /// <summary>
        /// 创建用户,并将用户添加到Membership角色中
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <param name="email">邮箱</param>
        /// <param name="password">密码</param>
        /// <param name="hasActived">是否需要激活，是的话发送激活邮件</param>
        /// <returns></returns>
        public MembershipCreateStatus CreateUser(string userName, string email, string password, bool hasActived)
        {
            MembershipCreateStatus createStatus;
            MembershipUser user = _provider.CreateUser(userName, password, email, null, null, !hasActived, Guid.NewGuid(), out createStatus);
            if (createStatus == MembershipCreateStatus.Success)
            {
                if (!roleService.IsUserInRole(userName, "Membership"))
                {
                    roleService.AddUserToRole(userName, "Membership");
                }

                if (hasActived)
                {
                    MembershipProfile p = (MembershipProfile)ProfileBase.Create(userName);
                    p.ActivateCode = Guid.NewGuid().ToString();
                    p.Save();
                    string activatecode = p.ActivateCode.ToString();

                    #region 发送激活邮件
                    string server = "mail.xinbotech.com";
                    string mailTo = email;
                    string mailFrom = "ifangxiang@xinbotech.com";
                    string mailFromName = "坊巷网会员中心";
                    string mailFromPwd = "ifangxiang";
                    string title = "坊巷网用户激活";
                    StringBuilder content = new StringBuilder();
                    content.AppendFormat("{0}：</br>", userName);
                    content.Append("感谢您注册坊巷网用户！</br>");
                    content.AppendFormat("您的登录名为：{0}  或  {1}</br>", userName, email);
                    content.Append("请点击以下链接激活您的账户：</br>");
                    content.AppendFormat("<a href='http://passport.ifangxiang.com/RegActive.aspx?username={0}&activatecode={1}'>http://passport.ifangxiang.com/reg_active.aspx?username={0}&activationcode={1}</a>", userName, activatecode);
                    content.Append("<hr></br>");
                    content.Append("这只是一封系统自动发送的邮件，请不要直接回复。 ");

                    try
                    {
                        EMailHelper.SendEMail(server, 587, mailTo, mailFrom, mailFromName, mailFromPwd, title, content.ToString());
                        log.Info(new LogMessage(user.UserName, user.ProviderUserKey.ToString(), LogObjectType.User, LogCode.USER_CREATE));
                    }
                    catch (Exception e)
                    {
                        log.Error(new LogMessage(user.UserName, user.ProviderUserKey.ToString(), LogObjectType.User, LogCode.USER_CREATE, "注册用户成功！发送邮件失败！", e));
                    }
                    #endregion
                }
            }
            else
            { 
                log.Error(new LogMessage(userName,"",LogObjectType.User,LogCode.USER_CREATE,"注册用户失败！"));
            }
            return createStatus;
        }

        /// <summary>
        /// 创建管理员
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <param name="email">邮箱</param>
        /// <param name="password">密码</param>
        /// <returns></returns>
        public MembershipCreateStatus CreateAdmin(string userName, string email, string password)
        {
            MembershipCreateStatus createStatus;
            MembershipUser user = _provider.CreateUser(userName, password, email, null, null, true, Guid.NewGuid(), out createStatus);
            if (createStatus == MembershipCreateStatus.Success)
            {
                if (!roleService.IsUserInRole(userName, "Administrators"))
                {
                    roleService.AddUserToRole(userName, "Administrators");
                }
            }
            return createStatus;
        }

        /// <summary>
        /// 激活用户
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <returns></returns>
        public bool ActivateUser(string userName, string activateCode)
        {
            try
            {
                MembershipProfile p = (MembershipProfile)ProfileBase.Create(userName);

                if (p.ActivateCode == activateCode)
                {
                    try
                    {
                        MembershipUser user = _provider.GetUser(userName, true);
                        user.IsApproved = true;
                        _provider.UpdateUser(user);

                        p.ActivateCode = string.Empty;
                        p.Save();

                        log.Info(new LogMessage(userName, userName, LogObjectType.User, LogCode.USER_ACTIVE, "激活码：" + activateCode));
                    }
                    catch (Exception e)
                    {
                        log.Error(new LogMessage(userName, userName, LogObjectType.User, LogCode.USER_ACTIVE, "", e));
                    }
                    return true;
                }
                else
                {
                    log.Error(new LogMessage(userName, userName, LogObjectType.User, LogCode.USER_ACTIVE, "激活失败！激活码：" + activateCode));
                    return false;
                }
            }
            catch (Exception e)
            {
                log.Fatal(new LogMessage(userName, userName, LogObjectType.User, LogCode.USER_ACTIVE, "激活失败！激活码：" + activateCode, e));
                return false;
            }
        }

        /// <summary>
        /// 后台激活用户
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <param name="adminName">管理员名称</param>
        /// <returns></returns>
        public bool ActivateUserByAdmin(string userName, string adminName)
        {
            try
            {
                MembershipUser user = _provider.GetUser(userName, true);
                if (user.IsApproved)
                {
                    user.IsApproved = false;
                }
                else
                {
                    user.IsApproved = true;
                }
                _provider.UpdateUser(user);
                log.Info(new LogMessage(adminName, userName, LogObjectType.User, LogCode.USER_ACTIVE, "后台操作状态成功！"));
                return true;
            }
            catch (Exception e)
            {
                log.Fatal(new LogMessage(adminName, userName, LogObjectType.User, LogCode.USER_ACTIVE, "后台操作状态失败！", e));
                return false;
            }
        }

        /// <summary>
        /// 后台解锁该用户
        /// </summary>
        /// <param name="adminName">管理员用户名</param>
        /// <param name="userName">普通用户名</param>
        /// <returns></returns>
        public bool UnlockUser(string adminName, string userName)
        {
            try
            {
                MembershipUser user = _provider.GetUser(userName, true);
                user.UnlockUser();
                log.Info(new LogMessage(adminName, userName, LogObjectType.User, LogCode.USER_ACTIVE, "成功地解锁该用户！"));
                return true;
            }
            catch (Exception e)
            {
                log.Fatal(new LogMessage(adminName, userName, LogObjectType.User, LogCode.USER_ACTIVE, "解锁该用户失败！", e));
                return false;
            }
        }

        /// <summary>
        /// 忘记密码请求
        /// </summary>
        /// <param name="email">邮箱</param>
        /// <returns>是否请求成功</returns>
        public bool ForgetPasswordRequest(string email)
        {
            bool result = false;
            MembershipService service = new MembershipService();
            string randomCode = service.CreateRandomCode(email);                              //生成随机码

            #region 发送修改密码地址邮件
            string username = _provider.GetUserNameByEmail(email);
            MembershipUser user = _provider.GetUser(username, true);
            string server = "mail.xinbotech.com";
            string mailTo = email;
            string mailFrom = "ifangxiang@xinbotech.com";
            string mailFromName = "坊巷网会员中心";
            string mailFromPwd = "ifangxiang";
            string title = "坊巷网用户修改密码";
            StringBuilder content = new StringBuilder();
            content.Append("请点击以下链接激活您的账户：</br>");
            content.AppendFormat("<a href='http://passport.ifangxiang.com/Editpwd.aspx?username={0}&randomcode={1}'>http://passport.ifangxiang.com/Editpwd.aspx?username={0}&randomcode={1}</a>", email, randomCode);
            content.Append("<hr></br>");
            content.Append("这只是一封系统自动发送的邮件，请不要直接回复。 ");

            try
            {
                EMailHelper.SendEMail(server, 587, mailTo, mailFrom, mailFromName, mailFromPwd, title, content.ToString());
                log.Info(new LogMessage(user.UserName, user.ProviderUserKey.ToString(), LogObjectType.User, LogCode.USER_FORGETPASSWORD));
                result = true;
            }
            catch (Exception e)
            {
                log.Error(new LogMessage(user.UserName, user.ProviderUserKey.ToString(), LogObjectType.User, LogCode.USER_FORGETPASSWORD, "发送邮件失败！", e));
            }
            #endregion
            return result;
        }

        /// <summary>
        /// 生成随机码
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <returns></returns>
        public string CreateRandomCode(string userNameOrEmail)
        {
            string userName = GetUserNameFromInput(userNameOrEmail);
            try
            {
                MembershipProfile p = (MembershipProfile)ProfileBase.Create(userName);
                if (p != null)
                {
                    p.RandomCode = Guid.NewGuid().ToString();
                    p.Save();
                    return p.RandomCode;
                }
                else
                {
                    return string.Empty;
                }
            }
            catch (Exception e)
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// 验证随机码
        /// </summary>
        /// <param name="userNameOrEmail">用户名或邮箱</param>
        /// <param name="randomCode">随机码</param>
        /// <returns></returns>
        public bool ValidateRandomCode(string userNameOrEmail, string randomCode)
        {
            string userName = GetUserNameFromInput(userNameOrEmail);
            try
            {
                MembershipProfile p = (MembershipProfile)ProfileBase.Create(userName);
                if (p != null)
                {
                    return p.RandomCode.Equals(randomCode);
                }
                else
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                log.Error(new LogMessage("生成验证码错误！", e));
                return false;
            }
        }

        /// <summary>
        /// 重置密码
        /// </summary>
        /// <param name="userNameOrEmail">用户名或邮箱</param>
        /// <param name="newPassword">新密码</param>
        /// <returns></returns>
        public bool ResetPassword(string userNameOrEmail, string newPassword)
        {
            string userName = GetUserNameFromInput(userNameOrEmail);
            MembershipUser user = _provider.GetUser(userName, false);
            bool result = user.ChangePassword(user.GetPassword(), newPassword);
            if (result)
            {
                log.Info(new LogMessage(userName, userName, LogObjectType.User, LogCode.USER_RESETPASSWORD));
            }
            else
            {
                log.Error(new LogMessage(userName, userName, LogObjectType.User, LogCode.USER_RESETPASSWORD));
            }
            return result;
        }

        #region 私有方法
        /// <summary>
        /// 由输入的用户名或邮箱获取用户名
        /// </summary>
        /// <param name="userNameOrEmail"></param>
        /// <returns></returns>
        private string GetUserNameFromInput(string userNameOrEmail)
        {
            string userName;
            if (Regex.IsMatch(userNameOrEmail, @"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"))
            {
                userName = _provider.GetUserNameByEmail(userNameOrEmail);
            }
            else
            {
                userName = userNameOrEmail;
            }
            return userName;
        }
        #endregion

        /// <summary>
        /// 获取用户信息数据
        /// </summary>
        /// <param name="pageIndex">当前页数</param>
        /// <param name="pageSize">每页的记录数</param>
        /// <param name="totalCount">相关记录的总数目</param>
        /// <param name="userNameOrEmail">查询条件</param>
        /// <returns></returns>
        public MembershipUserCollection GetUserList(int pageIndex, int pageSize, out int totalCount, string userNameOrEmail)
        {
            MembershipUserCollection collection = null;
            if (userNameOrEmail == null)
            {
                collection = _provider.GetAllUsers(pageIndex, pageSize, out totalCount);
            }
            else
            {
                if (Regex.IsMatch(userNameOrEmail, @"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"))
                {
                    collection = _provider.FindUsersByEmail(userNameOrEmail, pageIndex, pageSize, out totalCount);
                }
                else
                {
                    collection = _provider.FindUsersByName(userNameOrEmail, pageIndex, pageSize, out totalCount);
                }
            }
            return collection;
        }

        /// <summary>
        /// 获取管理员列表
        /// </summary>
        /// <param name="usernameToMatch">用户名</param>
        /// <returns></returns>
        public MembershipUserCollection GetAllAdmin(string usernameToMatch)
        {
            MembershipUserCollection users = new MembershipUserCollection();
            foreach (string username in roleService.GetAllAdmin(usernameToMatch))
            {
                users.Add(_provider.GetUser(username, false));
            }
            return users;
        }

        /// <summary>
        /// 根据用户名查找用户
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <returns></returns>
        public MembershipUser GetUserByName(string userName)
        {
            MembershipUser user = _provider.GetUser(userName, true);
            return user;
        }

        /// <summary>
        /// 修改个人密码
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="oldPassword">旧密码</param>
        /// <param name="newPassword">新密码</param>
        /// <returns></returns>
        public bool ChangeUserPassword(string username, string oldPassword, string newPassword)
        {
            bool result = _provider.ChangePassword(username, oldPassword, newPassword);
            if (result)
            {
                log.Info(new LogMessage(username, username, LogObjectType.User, LogCode.USER_RESETPASSWORD));
            }
            else
            {
                log.Error(new LogMessage(username, username, LogObjectType.User, LogCode.USER_RESETPASSWORD));
            }
            return result;
        }
    }
}